<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>超详细的Vagrant上手指南 | Kylin</title><meta name="keywords" content="vagrant"><meta name="author" content="Kylin"><meta name="copyright" content="Kylin"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="本文转载https:&#x2F;&#x2F;zhuanlan.zhihu.com&#x2F;p&#x2F;259833884  搭建 Linux 虚拟机，别再用 VirtualBox 从 .iso 文件安装了。 概述2020 年了，也许你已经习惯了 docker，习惯了在 XX 云上快速创建云主机，但是如果你想在个人电脑上安装虚拟机来搭建开发&#x2F;测试环境，Vagrant 仍然不失高效之选。  文末有和 docker 的对比说明。  本篇">
<meta property="og:type" content="article">
<meta property="og:title" content="超详细的Vagrant上手指南">
<meta property="og:url" content="https://www.codekylin.cn/47602.html">
<meta property="og:site_name" content="Kylin">
<meta property="og:description" content="本文转载https:&#x2F;&#x2F;zhuanlan.zhihu.com&#x2F;p&#x2F;259833884  搭建 Linux 虚拟机，别再用 VirtualBox 从 .iso 文件安装了。 概述2020 年了，也许你已经习惯了 docker，习惯了在 XX 云上快速创建云主机，但是如果你想在个人电脑上安装虚拟机来搭建开发&#x2F;测试环境，Vagrant 仍然不失高效之选。  文末有和 docker 的对比说明。  本篇">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://qiniu.codekylin.cn/img/20200418114719.jpg">
<meta property="article:published_time" content="2022-01-30T02:35:56.000Z">
<meta property="article:modified_time" content="2022-01-30T02:37:31.052Z">
<meta property="article:author" content="Kylin">
<meta property="article:tag" content="vagrant">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://qiniu.codekylin.cn/img/20200418114719.jpg"><link rel="shortcut icon" href="https://qiniu.codekylin.cn/img/20200807181548.png"><link rel="canonical" href="https://www.codekylin.cn/47602"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//www.google-analytics.com" crossorigin=""/><link rel="preconnect" href="//hm.baidu.com"/><link rel="preconnect" href="//fonts.googleapis.com" crossorigin=""/><meta name="google-site-verification" content="gzeyWstt6NoTZKh7YFYNLNziL8HIZ8YH2Ug7xTDX5-Y"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css" media="print" onload="this.media='all'"><script>var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?f76c34daefe747deee7c7be3ead2ba80";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script><script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-159334016-1"></script><script>window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-159334016-1');
</script><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Titillium+Web" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"search.xml","languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"简"},
  noticeOutdate: {"limitDay":90,"position":"top","messagePrev":"自上次更新以来已经","messageNext":"天，文章的内容可能已过时或存在差异。"},
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: {"limitCount":50000,"languages":{"author":"作者: Kylin","link":"链接: ","source":"来源: Kylin","info":"著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"}},
  lightbox: 'fancybox',
  Snackbar: {"chs_to_cht":"你已切换为繁体","cht_to_chs":"你已切换为简体","day_to_night":"你已切换为深色模式","night_to_day":"你已切换为浅色模式","bgLight":"#FF0000","bgDark":"#2d3035","position":"bottom-left"},
  source: {
    jQuery: 'https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js',
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/js/jquery.justifiedGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/css/justifiedGallery.min.css'
    },
    fancybox: {
      js: 'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.js',
      css: 'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: true,
  isanchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = { 
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2022-01-30 10:37:31'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
          const isLightMode = window.matchMedia('(prefers-color-scheme: light)').matches
          const isNotSpecified = window.matchMedia('(prefers-color-scheme: no-preference)').matches
          const hasNoSupport = !isDarkMode && !isLightMode && !isNotSpecified

          if (t === undefined) {
            if (isLightMode) activateLightMode()
            else if (isDarkMode) activateDarkMode()
            else if (isNotSpecified || hasNoSupport) {
              const now = new Date()
              const hour = now.getHours()
              const isNight = hour <= 6 || hour >= 18
              isNight ? activateDarkMode() : activateLightMode()
            }
            window.matchMedia('(prefers-color-scheme: dark)').addListener(function (e) {
              if (saveToLocal.get('theme') === undefined) {
                e.matches ? activateDarkMode() : activateLightMode()
              }
            })
          } else if (t === 'light') activateLightMode()
          else activateDarkMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const fontSizeVal = saveToLocal.get('global-font-size')
    if (fontSizeVal !== undefined) {
      document.documentElement.style.setProperty('--global-font-size', fontSizeVal + 'px')
    }
    })(window)</script><link rel="stylesheet" href="https://qiniu.codekylin.cn/github/img/img/custom.css"><link rel="stylesheet" href="//at.alicdn.com/t/font_1993646_z05rabxf05h.css"><link rel="stylesheet" href="https://qiniu.codekylin.cn/github/img/img/icon.css"><meta name="generator" content="Hexo 5.4.0"><link rel="alternate" href="/atom.xml" title="Kylin" type="application/atom+xml">
</head><body><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="author-avatar"><img class="avatar-img" data-lazy-src="https://qiniu.codekylin.cn/img/20200807181526.jpg" onerror="onerror=null;src='https://qiniu.codekylin.cn/github/img/friend_404.gif'" alt="avatar"/></div><div class="site-data"><div class="data-item is-center"><div class="data-item-link"><a href="/archives/"><div class="headline">文章</div><div class="length-num">362</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/tags/"><div class="headline">标签</div><div class="length-num">427</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/categories/"><div class="headline">分类</div><div class="length-num">101</div></a></div></div></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fa fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fa fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fa fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fa fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fa fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fa fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://qiniu.codekylin.cn/img/20200418114719.jpg')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">Kylin</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fa fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fa fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fa fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fa fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fa fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fa fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">超详细的Vagrant上手指南</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2022-01-30T02:35:56.000Z" title="发表于 2022-01-30 10:35:56">2022-01-30</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2022-01-30T02:37:31.052Z" title="更新于 2022-01-30 10:37:31">2022-01-30</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/vagrant/">vagrant</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">8.5k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>33分钟</span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><blockquote>
<p>本文转载<a target="_blank" rel="noopener" href="https://zhuanlan.zhihu.com/p/259833884">https://zhuanlan.zhihu.com/p/259833884</a></p>
</blockquote>
<p>搭建 Linux 虚拟机，别再用 VirtualBox 从 .iso 文件安装了。</p>
<h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>2020 年了，也许你已经习惯了 docker，习惯了在 XX 云上快速创建云主机，但是如果你想在个人电脑上安装虚拟机来搭建开发/测试环境，Vagrant 仍然不失高效之选。</p>
<blockquote>
<p>文末有和 docker 的对比说明。</p>
</blockquote>
<p><strong>本篇内容字数过万，收藏的同时别忘了点个赞，谢谢！</strong></p>
<h2 id="安装软件"><a href="#安装软件" class="headerlink" title="安装软件"></a>安装软件</h2><p><strong>安装 VirtualBox</strong></p>
<p>进入 VirtualBox 的<a href="https://link.zhihu.com/?target=https%3A//www.virtualbox.org/">主页</a>，点击大大的下载按钮，即可进入下载页面。</p>
<p>VirtualBox 是一个跨平台的虚拟化工具，支持多个操作系统，根据自己的情况选择对应的版本下载即可。</p>
<p>注意，除了主程序，还要把对应的<strong>扩展包程序</strong>也一并下载了。有些高级特性，比如 USB 3.0 等需要扩展包的支持。</p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://pic3.zhimg.com/80/v2-a1225a9c7e8d405a35588542342cc6da_1440w.jpg" alt="img"></p>
<p>在安装完主程序后，直接双击扩展包文件即可安装扩展包。</p>
<blockquote>
<p>下载页面先别关，后面还要用到。</p>
</blockquote>
<p><strong>安装 Vagrant</strong></p>
<p>在 <a href="https://link.zhihu.com/?target=https%3A//www.vagrantup.com/">Vagant 网站</a>下载最新的版本，根据自己的操作系统选择对应的版本下载即可。</p>
<p>注意，Vagrant 是没有图形界面的，所以安装完成后也没有桌面快捷方式。具体使用方法，接下来会详细说明。</p>
<p>Vagrant 的安装程序会自动把安装路径加入到 PATH 环境变量，所以，这时候可以通过命令行执行 <code>vagrant version</code> 检查是否安装成功：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&gt; vagrant version</span><br><span class="line">Installed Version: 2.2.7</span><br><span class="line">Latest Version: 2.2.8</span><br></pre></td></tr></table></figure>

<h2 id="配置虚机存放位置"><a href="#配置虚机存放位置" class="headerlink" title="配置虚机存放位置"></a>配置虚机存放位置</h2><p>创建虚拟机会占用较多的磁盘空间，在 Windows 系统下默认的虚机创建位置是在 C 盘，所以最好配置到其它地方。</p>
<p><strong>配置 VirtualBox</strong></p>
<p>启动 VirtualBox 后，通过菜单 <code>管理</code> -&gt; <code>全局设定</code>，或者按下快捷键 <code>Ctrl + g</code>，在全局设定对话框中，修改 <code>默认虚拟电脑位置</code>，指定一个容量较大的磁盘。</p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://pic3.zhimg.com/80/v2-4371dddf89e26ad3de5dded485a28eaa_1440w.jpg" alt="img"></p>
<p><strong>配置 Vagrant</strong></p>
<p>通过 Vagrant 创建虚机需要先导入镜像文件，也就是 <code>box</code>，它们默认存储的位置在用户目录下的 <code>.vagrant.d</code> 目录下，对于 Windows 系统来说，就是 <code>C:\Users\用户名\.vagrant.d</code>。</p>
<p>如果后续可能会用到较多镜像，或者你的 C 盘空间比较紧缺，可以通过设置环境变量 <code>VAGRANT_HOME</code> 来设置该目录。</p>
<p>在 Windows 系统中，可以这样操作：新建系统环境变量，环境变量名为 <code>VAGRANT_HOME</code>，变量值为 <code>E:\VirtualBox\.vagrant.d</code></p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://pic4.zhimg.com/80/v2-50a5223ae160aa6452991357a29b62b3_1440w.jpg" alt="img"></p>
<blockquote>
<p><strong>注意</strong>，最后这个 <code>.vagrant.d</code> 目录名称不是必须的，但是建议保持一致，这样一眼看上去就能知道这个目录是做什么用处的了。</p>
</blockquote>
<h2 id="下载虚机镜像"><a href="#下载虚机镜像" class="headerlink" title="下载虚机镜像"></a>下载虚机镜像</h2><p>使用 Vagrant 创建虚机时，需要指定一个镜像，也就是 <code>box</code>。开始这个 box 不存在，所以 Vagrant 会先从网上下载，然后缓存在本地目录中。</p>
<p>Vagrant 有一个<a href="https://link.zhihu.com/?target=https%3A//app.vagrantup.com/boxes/search">镜像网站</a>，里面列出了都有哪些镜像可以用，并且提供了操作文档。</p>
<p>但是这里默认下载往往会比较慢，所以下面我会介绍如何在其它地方下载到基础镜像，然后按照自己的需要重置。如果网速较好，下载顺利的朋友可以选择性地跳过部分内容。</p>
<p>下面我给出最常用的两个 Linux 操作系统镜像的下载地址：</p>
<p><strong>CentOS</strong></p>
<p>CentOS 的镜像下载网站是： <a href="https://link.zhihu.com/?target=http%3A//cloud.centos.org/centos/">http://cloud.centos.org/centos/</a></p>
<p>在其中选择自己想要下载的版本，列表中有一个 <code>vagrant</code> 目录，里面是专门为 vagrant 构建的镜像。选择其中的 <code>.box</code> 后缀的文件下载即可。这里可以使用下载工具，以较快的速度下载下来。</p>
<p>这里我们选择下载的是 <a href="https://link.zhihu.com/?target=http%3A//cloud.centos.org/centos/7/vagrant/x86_64/images/CentOS-7.box">CentOS 7 的最新版本</a></p>
<p><strong>Ubuntu</strong></p>
<p>Ubuntu 的镜像下载网站是： <a href="https://link.zhihu.com/?target=http%3A//cloud-images.ubuntu.com/">http://cloud-images.ubuntu.com/</a></p>
<p>同样先选择想要的版本，然后选择针对 vagrant 的 <code>.box</code> 文件即可。</p>
<p>如果这里官网的速度较慢，还可以从 <a href="https://link.zhihu.com/?target=https%3A//mirror.tuna.tsinghua.edu.cn/ubuntu-cloud-images/">清华大学的镜像站</a> 下载。</p>
<p>下面的例子以 CentOS 7 为例，使用其它版本操作系统的也可以参考。</p>
<h2 id="添加-box"><a href="#添加-box" class="headerlink" title="添加 box"></a>添加 box</h2><p>接下来我们需要将下载后的 <code>.box</code> 文件添加到 vagrant 中。</p>
<p>Vagrant 没有 GUI，只能从命令行访问，先启动一个命令行，然后执行:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ vagrant box list</span><br><span class="line">There are no installed boxes! Use `vagrant box add` to add some.</span><br></pre></td></tr></table></figure>

<p>提示现在还没有 box。如果这是第一次运行，此时 <code>VAGRANT_HOME</code> 目录下会自动生成若干的文件和文件夹，其中有一个 <code>boxes</code> 文件夹，这就是要存放 box 文件的地方。</p>
<p>执行 <code>vagrant box add</code> 命令添加 box:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">$ vagrant box add e:\Downloads\CentOS-7.box --name centos-7</span><br><span class="line">==&gt; box: Box file was not detected as metadata. Adding it directly...</span><br><span class="line">==&gt; box: Adding box &#x27;centos-7&#x27; (v0) for provider:</span><br><span class="line">    box: Unpacking necessary files from: file:///e:/Downloads/CentOS-7.box</span><br><span class="line">    box:</span><br><span class="line">==&gt; box: Successfully added box &#x27;centos-7&#x27; (v0) for &#x27;virtualbox&#x27;!</span><br></pre></td></tr></table></figure>

<p>命令后面跟着的是下载的文件路径，并且通过 <code>--name centos-7</code> 为这个 box 指定一个名字。</p>
<p>后面创建虚机都需要指定这个名字，所以尽量把名字取得简短一点，同时也要能标识出这个镜像的信息（我们后面会定制自己的基础镜像，所以这里可以简单点）。</p>
<p>再次查询，可以看到有了一个 box：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ vagrant box list</span><br><span class="line">centos-7 (virtualbox, 0)</span><br></pre></td></tr></table></figure>

<h2 id="Vagrant-基本操作"><a href="#Vagrant-基本操作" class="headerlink" title="Vagrant 基本操作"></a>Vagrant 基本操作</h2><h3 id="新建虚机"><a href="#新建虚机" class="headerlink" title="新建虚机"></a>新建虚机</h3><p>创建一个目录，先执行 <code>vagrant init</code>：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir demo</span><br><span class="line">$ cd demo</span><br><span class="line">$ vagrant init centos-7</span><br><span class="line">A `Vagrantfile` has been placed in this directory. You are now</span><br><span class="line">ready to `vagrant up` your first virtual environment! Please read</span><br><span class="line">the comments in the Vagrantfile as well as documentation on</span><br><span class="line">`vagrantup.com` for more information on using Vagrant.</span><br></pre></td></tr></table></figure>

<p>其中的 <code>centos-7</code> 就是我们要使用的 <code>box</code> 名字。</p>
<p>这个命令只是为我们生成一个 <code>Vagrantfile</code>，所以，这里的名字没指定或者写错了都没关系，后面会介绍如何编辑这个 <code>Vagrantfile</code> 来修改。</p>
<h3 id="启动虚机"><a href="#启动虚机" class="headerlink" title="启动虚机"></a>启动虚机</h3><p>我们等会再来细看这个文件，现在直接按照提示执行 <code>vagrant up</code>：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">$ vagrant up</span><br><span class="line">Bringing machine &#x27;default&#x27; up with &#x27;virtualbox&#x27; provider...</span><br><span class="line">==&gt; default: Importing base box &#x27;centos-7&#x27;...</span><br><span class="line">==&gt; default: Matching MAC address for NAT networking...</span><br><span class="line">==&gt; default: Setting the name of the VM: demo_default_1588406874156_65036</span><br><span class="line">==&gt; default: Clearing any previously set network interfaces...</span><br><span class="line">==&gt; default: Preparing network interfaces based on configuration...</span><br><span class="line">    default: Adapter 1: nat</span><br><span class="line">==&gt; default: Forwarding ports...</span><br><span class="line">    default: 22 (guest) =&gt; 2222 (host) (adapter 1)</span><br><span class="line">==&gt; default: Booting VM...</span><br><span class="line">==&gt; default: Waiting for machine to boot. This may take a few minutes...</span><br><span class="line">    default: SSH address: 127.0.0.1:2222</span><br><span class="line">    default: SSH username: vagrant</span><br><span class="line">    default: SSH auth method: private key</span><br></pre></td></tr></table></figure>

<p>正常的情况下，不到一分钟应该就能启动成功了。</p>
<blockquote>
<p>这里我遇到点问题，2222 端口转发出现未知错误，造成 vagrant 的启动超时。检查了这个端口并没被占用，同时更改大一点的端口可以转发成功，所以应该是系统哪里有点问题。在后面我介绍了如何处理，如果你也遇到和我一样的情况，可先跳到下面查看。</p>
</blockquote>
<p>注意到这里包含的信息：</p>
<ul>
<li>虚机名称：<code>demo_default_1588406874156_65036</code>（想改？最后有提）</li>
<li>网卡：<code>Adapter 1: nat</code>，第一块网卡，NAT 模式，这是固定的</li>
<li>端口转发：<code>22 (guest) =&gt; 2222 (host) (adapter 1)</code>，把虚机的 22 端口，映射到宿主机的 2222 端口上，这样就可以通过 <code>127.0.0.1:2222</code> 访问虚拟机了</li>
<li>SSH 用户名：<code>vagrant</code>，这里使用 <code>private key</code> 登录</li>
</ul>
<blockquote>
<p>密码也是 <code>vagrant</code>，但是密码方式仅供直接登录，是不能通过 SSH 登录的。</p>
</blockquote>
<h3 id="查看虚机状态"><a href="#查看虚机状态" class="headerlink" title="查看虚机状态"></a>查看虚机状态</h3><p>执行下面的命令可以查看虚机的状态：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">vagrant status</span><br><span class="line"></span><br><span class="line">Current machine states:</span><br><span class="line"></span><br><span class="line">default                   running (virtualbox)</span><br><span class="line"></span><br><span class="line">The VM is running. To stop this VM, you can run `vagrant halt` to</span><br><span class="line">shut it down forcefully, or you can run `vagrant suspend` to simply</span><br><span class="line">suspend the virtual machine. In either case, to restart it again,</span><br><span class="line">simply run `vagrant up`.</span><br></pre></td></tr></table></figure>

<p>该命令还提示了如何操作虚机，我们继续一一介绍</p>
<h3 id="连接虚机"><a href="#连接虚机" class="headerlink" title="连接虚机"></a>连接虚机</h3><p>如果启动没问题，接下来执行 <code>vagrant ssh</code> 就能以 <code>vagrant</code> 用户直接登入虚机中。</p>
<p><code>root</code> 用户没有默认密码，也不能直接登录。需要 root 权限的命令可以通过在命令前添加 <code>sudo</code> 来执行，也可以执行 <code>sudo -i</code> 直接切换到 <code>root</code> 用户。</p>
<p>这时候打开 VirtualBox 程序，可以看到自动创建的虚机：</p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://pic4.zhimg.com/80/v2-34eb6f9e2fc34aea3ae2d4d80328ff7f_1440w.jpg" alt="img"></p>
<p>我们也可以在 VirtualBox 的终端上登录系统，默认的登录用户名和密码都是 <code>vagrant</code>。</p>
<p>当然还可以使用其它的 SSH 连接工具例如 XShell，SecureCRT 连接，但是这里默认网卡使用的是 NAT 模式，没有指定 IP，实际应用并不方便，我们在后面介绍网络配置时再详细介绍如何连接虚机。</p>
<h3 id="停止虚机"><a href="#停止虚机" class="headerlink" title="停止虚机"></a>停止虚机</h3><p>执行下面的命令可以关闭虚机：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vagrant halt</span><br></pre></td></tr></table></figure>

<p>直接在 VirtualBox 上关闭虚机，或者直接在虚机内部执行 <code>poweroff</code> 命令也都是可以的。</p>
<h3 id="暂停虚机"><a href="#暂停虚机" class="headerlink" title="暂停虚机"></a>暂停虚机</h3><p>执行下面的命令可以暂停虚机：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vagrant suspend</span><br></pre></td></tr></table></figure>

<h3 id="恢复虚机"><a href="#恢复虚机" class="headerlink" title="恢复虚机"></a>恢复虚机</h3><p>执行下面的命令把暂停状态的虚机恢复运行：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vagrant resume</span><br></pre></td></tr></table></figure>

<p><strong>注意：</strong> 不管虚机是关闭还是暂停状态，甚至是 error 状态，都可以执行 <code>vagrant up</code> 来让虚机恢复运行。</p>
<h3 id="重载虚机"><a href="#重载虚机" class="headerlink" title="重载虚机"></a>重载虚机</h3><p>执行下面的命令会重启虚机，并且重新加载 <code>Vagrantfile</code> 中的配置信息：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vagrant reload</span><br></pre></td></tr></table></figure>

<h3 id="删除虚机"><a href="#删除虚机" class="headerlink" title="删除虚机"></a>删除虚机</h3><p>最后，执行下面的命令可以彻底删除虚机，包括整个虚机文件：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vagrant destroy</span><br></pre></td></tr></table></figure>

<p><strong>注意：</strong> 在当前这个小例子中，上面所有的 <code>vagrant</code> 命令都需要在 <code>Vagrantfile</code> 所在的目录下执行。</p>
<h2 id="初识-Vagrantfile"><a href="#初识-Vagrantfile" class="headerlink" title="初识 Vagrantfile"></a>初识 Vagrantfile</h2><p>先来认识一下默认的 <code>Vagrantfile</code> 文件，使用带语法高亮的文本编辑器（例如 VSCode） 打开:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"># -*- mode: ruby -*-</span><br><span class="line"># vi: set ft=ruby :</span><br><span class="line"></span><br><span class="line"># All Vagrant configuration is done below. The &quot;2&quot; in Vagrant.configure</span><br><span class="line"># configures the configuration version (we support older styles for</span><br><span class="line"># backwards compatibility). Please don&#x27;t change it unless you know what</span><br><span class="line"># you&#x27;re doing.</span><br><span class="line">Vagrant.configure(&quot;2&quot;) do |config|</span><br><span class="line">  # The most common configuration options are documented and commented below.</span><br><span class="line">  # For a complete reference, please see the online documentation at</span><br><span class="line">  # https://docs.vagrantup.com.</span><br><span class="line"></span><br><span class="line">  # Every Vagrant development environment requires a box. You can search for</span><br><span class="line">  # boxes at https://vagrantcloud.com/search.</span><br><span class="line">  config.vm.box = &quot;centos-7&quot;</span><br><span class="line"></span><br><span class="line">  # Disable automatic box update checking. If you disable this, then</span><br><span class="line">  # boxes will only be checked for updates when the user runs</span><br><span class="line">  # `vagrant box outdated`. This is not recommended.</span><br><span class="line">  # config.vm.box_check_update = false</span><br><span class="line"></span><br><span class="line">  # Create a forwarded port mapping which allows access to a specific port</span><br><span class="line">  # within the machine from a port on the host machine. In the example below,</span><br><span class="line">  # accessing &quot;localhost:8080&quot; will access port 80 on the guest machine.</span><br><span class="line">  # NOTE: This will enable public access to the opened port</span><br><span class="line">  # config.vm.network &quot;forwarded_port&quot;, guest: 80, host: 8080</span><br><span class="line"></span><br><span class="line">  # Create a forwarded port mapping which allows access to a specific port</span><br><span class="line">  # within the machine from a port on the host machine and only allow access</span><br><span class="line">  # via 127.0.0.1 to disable public access</span><br><span class="line">  # config.vm.network &quot;forwarded_port&quot;, guest: 80, host: 8080, host_ip: &quot;127.0.0.1&quot;</span><br><span class="line"></span><br><span class="line">  # Create a private network, which allows host-only access to the machine</span><br><span class="line">  # using a specific IP.</span><br><span class="line">  # config.vm.network &quot;private_network&quot;, ip: &quot;192.168.33.10&quot;</span><br><span class="line"></span><br><span class="line">  # Create a public network, which generally matched to bridged network.</span><br><span class="line">  # Bridged networks make the machine appear as another physical device on</span><br><span class="line">  # your network.</span><br><span class="line">  # config.vm.network &quot;public_network&quot;</span><br><span class="line"></span><br><span class="line">  # Share an additional folder to the guest VM. The first argument is</span><br><span class="line">  # the path on the host to the actual folder. The second argument is</span><br><span class="line">  # the path on the guest to mount the folder. And the optional third</span><br><span class="line">  # argument is a set of non-required options.</span><br><span class="line">  # config.vm.synced_folder &quot;../data&quot;, &quot;/vagrant_data&quot;</span><br><span class="line"></span><br><span class="line">  # Provider-specific configuration so you can fine-tune various</span><br><span class="line">  # backing providers for Vagrant. These expose provider-specific options.</span><br><span class="line">  # Example for VirtualBox:</span><br><span class="line">  #</span><br><span class="line">  # config.vm.provider &quot;virtualbox&quot; do |vb|</span><br><span class="line">  #   # Display the VirtualBox GUI when booting the machine</span><br><span class="line">  #   vb.gui = true</span><br><span class="line">  #</span><br><span class="line">  #   # Customize the amount of memory on the VM:</span><br><span class="line">  #   vb.memory = &quot;1024&quot;</span><br><span class="line">  # end</span><br><span class="line">  #</span><br><span class="line">  # View the documentation for the provider you are using for more</span><br><span class="line">  # information on available options.</span><br><span class="line"></span><br><span class="line">  # Enable provisioning with a shell script. Additional provisioners such as</span><br><span class="line">  # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the</span><br><span class="line">  # documentation for more information about their specific syntax and use.</span><br><span class="line">  # config.vm.provision &quot;shell&quot;, inline: &lt;&lt;-SHELL</span><br><span class="line">  #   apt-get update</span><br><span class="line">  #   apt-get install -y apache2</span><br><span class="line">  # SHELL</span><br><span class="line">end</span><br></pre></td></tr></table></figure>

<p>这是一个 Ruby 语法的文件，因为 Vagrant 就是用 Ruby 编写的。如果编辑器没有语法高亮可以手动设置文件类型为 Ruby。</p>
<p>这个缺省文件内容几乎都是注释，提示有哪些配置项可以修改，我们不需要去学 Ruby 编程也可以照葫芦画瓢的完成基本的配置。</p>
<blockquote>
<p>当然，如果会 Ruby 编程的可以在此实现更高级的作用，但是绝大多数人用不着。</p>
</blockquote>
<p>刨除注释，这个文件的实际生效内容实际只有 3 行:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Vagrant.configure(&quot;2&quot;) do |config|</span><br><span class="line">  config.vm.box = &quot;centos-7&quot;</span><br><span class="line">end</span><br></pre></td></tr></table></figure>

<p>首尾两行组成一个代码块结构，不要去动它，除非你知道自己在干什么。我们平常只需要编辑这其中的配置项。</p>
<p>这里的 <code>config.vm.box</code> 对应的就是虚机的镜像，也就是 box 文件，这是唯一必填的配置项。</p>
<p>特别提醒，<code>Vagrantfile</code> 文件名是固定的写法，大小写也要完全一样，修改了就不认识了。</p>
<h2 id="自定义配置-Vagrantfile"><a href="#自定义配置-Vagrantfile" class="headerlink" title="自定义配置 Vagrantfile"></a>自定义配置 Vagrantfile</h2><p>下面我将针对这份默认的 <code>Vagrantfile</code> 内容，逐个讲解其中的配置含义和如何根据实际情况修改。</p>
<h3 id="配置端口转发"><a href="#配置端口转发" class="headerlink" title="配置端口转发"></a>配置端口转发</h3><p>端口转发（Port forward）又叫端口映射，就是把虚机的某个端口，映射到宿主机的端口上。这样就能在宿主机上访问到虚拟机中的服务。</p>
<p>例如启动虚机时，默认的 <code>22 (guest) =&gt; 2222 (host) (adapter 1)</code> 就是把虚机的 SSH 服务端口（<code>22</code>）映射到宿主机的 <code>2222</code> 端口，这样直接在宿主机通过 ssh 客户端访问 <code>127.0.0.1:2222</code> 端口就等价于访问虚拟机的 <code>22</code> 端口。</p>
<p>下面这两段配置就是教我们如何配置额外的端口转发规则，例如把 Web 服务也映射出来：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"># Create a forwarded port mapping which allows access to a specific port</span><br><span class="line"># within the machine from a port on the host machine. In the example below,</span><br><span class="line"># accessing &quot;localhost:8080&quot; will access port 80 on the guest machine.</span><br><span class="line"># NOTE: This will enable public access to the opened port</span><br><span class="line"># config.vm.network &quot;forwarded_port&quot;, guest: 80, host: 8080</span><br><span class="line"></span><br><span class="line"># Create a forwarded port mapping which allows access to a specific port</span><br><span class="line"># within the machine from a port on the host machine and only allow access</span><br><span class="line"># via 127.0.0.1 to disable public access</span><br><span class="line"># config.vm.network &quot;forwarded_port&quot;, guest: 80, host: 8080, host_ip: &quot;127.0.0.1&quot;</span><br></pre></td></tr></table></figure>

<p>实际上设置端口转发这个功能并不实用，一个很明显的问题就是如果启动多个虚机，很容易就出现宿主机上端口冲突的问题。即使没有端口冲突，使用起来也不方便，我个人不推荐使用的，可以把这部分配置直接删掉。直接使用下面的私有网络。</p>
<p>这个功能是虚拟机软件提供的，可以在虚机的网卡设置中展开高级选项，找到相关的配置：</p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://pic1.zhimg.com/80/v2-4d1b277ecb3544b2b438b98388fea778_1440w.jpg" alt="img"></p>
<p>还有个地方需要注意，默认的 SSH 端口映射在这里没法直接修改。比如像我这样，2222 端口出现莫名问题，如果想要把 22 端口转发到其它端口如 22222，直接添加下面这样的配置是<strong>没用</strong>的：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">config.vm.network &quot;forwarded_port&quot;, guest: 22, host: 22222</span><br></pre></td></tr></table></figure>

<p>它会在原来的基础上新加一个端口转发规则，而不是替代原来的，必须要先强制关闭掉默认的那条规则:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">config.vm.network &quot;forwarded_port&quot;, guest: 22, host: 2222, id: &quot;ssh&quot;, disabled: &quot;true&quot;</span><br><span class="line">config.vm.network &quot;forwarded_port&quot;, guest: 22, host: 22222</span><br></pre></td></tr></table></figure>

<h3 id="配置私有网络"><a href="#配置私有网络" class="headerlink" title="配置私有网络"></a>配置私有网络</h3><p>下面这段配置用来配置私有网络，实际上对应的是 VirtualBox 的主机网络，也就是 HostOnly 网络。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"># Create a private network, which allows host-only access to the machine</span><br><span class="line"># using a specific IP.</span><br><span class="line"># config.vm.network &quot;private_network&quot;, ip: &quot;192.168.33.10&quot;</span><br></pre></td></tr></table></figure>

<p>取消注释最下面一行，就可以为虚机设置指定的私有网络地址：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">config.vm.network &quot;private_network&quot;, ip: &quot;192.168.33.10&quot;</span><br></pre></td></tr></table></figure>

<p>如果这个网段的主机网络在 VirtualBox 中不存在，Vagrant 会在启动虚机时自动创建。所以，如果你想要利用已有的网络，请查看现有<strong>主机网络</strong>配置：</p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://pic3.zhimg.com/80/v2-a7962b522cc5584e95340f0aee31e902_1440w.jpg" alt="img"></p>
<p>最好这个网络也不要启用 DHCP，完全由自己来分配地址，这样更加清楚。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">config.vm.network &quot;private_network&quot;, ip: &quot;192.168.56.10&quot;</span><br></pre></td></tr></table></figure>

<p>修改完成后，执行 <code>vagrant reload</code> 命令重建虚机，就能看到多出来的网卡了。</p>
<p>私有网络实际也可以直接使用 DHCP，但是并不推荐：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">config.vm.network &quot;private_network&quot;, type: &quot;dhcp&quot;</span><br></pre></td></tr></table></figure>

<h3 id="配置公共网络"><a href="#配置公共网络" class="headerlink" title="配置公共网络"></a>配置公共网络</h3><p>下面这条配置用来配置公共网络：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># Create a public network, which generally matched to bridged network.</span><br><span class="line"># Bridged networks make the machine appear as another physical device on</span><br><span class="line"># your network.</span><br><span class="line"># config.vm.network &quot;public_network&quot;</span><br></pre></td></tr></table></figure>

<p>正如注释所说，这里通常对应的就是桥接网络。实际开发场景下，我们极少会需要把虚机暴露到公共网络上，这样既不安全，也没有必要。</p>
<p>默认所起的第 1 个 NAT 网络已经保证了虚机可以上互联网，而私有网络保证了宿主机和虚机，以及虚机和虚机之间的通信。如果有对外暴露服务的需求，还可以使用端口转发。我实在想不出什么情况下是必须要用桥接网络的。</p>
<p>所以这部分配置可以直接删除，如确有使用的，可以参考 <a href="https://link.zhihu.com/?target=https%3A//www.vagrantup.com/docs/networking/public_network.html">官方文档</a>。</p>
<h3 id="配置同步文件夹"><a href="#配置同步文件夹" class="headerlink" title="配置同步文件夹"></a>配置同步文件夹</h3><p>下面的配置项用来配置同步文件夹:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># Share an additional folder to the guest VM. The first argument is</span><br><span class="line"># the path on the host to the actual folder. The second argument is</span><br><span class="line"># the path on the guest to mount the folder. And the optional third</span><br><span class="line"># argument is a set of non-required options.</span><br><span class="line"># config.vm.synced_folder &quot;../data&quot;, &quot;/vagrant_data&quot;</span><br></pre></td></tr></table></figure>

<p>在启动虚机的时候，我们可以看到这样的提示：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">==&gt; default: Machine booted and ready!</span><br><span class="line">==&gt; default: Checking for guest additions in VM...</span><br><span class="line">    default: No guest additions were detected on the base box for this VM! Guest</span><br><span class="line">    default: additions are required for forwarded ports, shared folders, host only</span><br><span class="line">    default: networking, and more. If SSH fails on this machine, please install</span><br><span class="line">    default: the guest additions and repackage the box to continue.</span><br><span class="line">    default:</span><br><span class="line">    default: This is not an error message; everything may continue to work properly,</span><br><span class="line">    default: in which case you may ignore this message.</span><br><span class="line">==&gt; default: Configuring and enabling network interfaces...</span><br><span class="line">==&gt; default: Rsyncing folder: /cygdrive/c/Users/Davy/demo/ =&gt; /vagrant</span><br></pre></td></tr></table></figure>

<p>先注意最后一行的提示：<code>Rsyncing folder: /cygdrive/c/Users/Davy/demo/ =&gt; /vagrant</code></p>
<ul>
<li><code>/cygdrive/c/Users/Davy/demo/</code> 这是宿主机的本地目录，也就是 <code>Vagrantfile</code> 所在的目录。</li>
<li><code>/vagrant</code> 是虚拟机内部的路径</li>
<li><code>Rsyncing</code> 表示同步的方式是 Rsync</li>
</ul>
<blockquote>
<p>宿主机目录中出现 <code>/cygdrive</code> 是因为 Vagrant 程序用到了 Cygwin，它是在 Windows 系统中兼容 Linux/POSIX 的模拟层。可以把 <code>/cygdrive</code> 看成是虚拟的根目录。</p>
</blockquote>
<p>这是 Vagrant 默认的同步文件夹设置，别忘了 Vagrant 的作用是用来搭建开发环境的。所以它假定了当前目录是我们的开发项目所在目录，自动把本地的项目目录同步到虚机中，就可以快速的开始开发调试工作了。</p>
<ol>
<li>在 <code>demo</code> 目录下创建一些文件，例如 <code>hello.py</code></li>
<li>执行 <code>vagrant reload</code>，重启虚机</li>
<li>在虚机启动完成后登录到虚机内，操作如下：</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$ vagrant ssh</span><br><span class="line">Last login: Sat May  2 16:25:00 2020 from 10.0.2.2</span><br><span class="line">[vagrant@localhost ~]$ cd /vagrant/</span><br><span class="line">[vagrant@localhost vagrant]$ ls</span><br><span class="line">hello.py  Vagrantfile</span><br><span class="line">[vagrant@localhost vagrant]$ python hello.py</span><br><span class="line">helloworld</span><br></pre></td></tr></table></figure>

<p>这种同步方式在大多数情况下都能提供便利，不过也有不足之处：</p>
<ul>
<li>同步是一次性的，即只有启动虚机的时候执行，也就是说改了代码必须要重启一次虚机</li>
<li>单向的，即只能从宿主机同步到虚拟机，也就是说在虚机内的改动不会同步到外面</li>
<li>需要拷贝文件，如果要同步的文件数量较多，会占用更多的磁盘空间</li>
</ul>
<p>让我们按照默认配置的提示来新加一条同步文件夹配置试试：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">config.vm.synced_folder &quot;../data&quot;, &quot;/vagrant_data&quot;</span><br></pre></td></tr></table></figure>

<p>注意，别忘了先在宿主机上创建 <code>data</code> 文件夹，重启虚机可能看到下面的错误提示：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">==&gt; default: Rsyncing folder: /cygdrive/c/Users/Davy/demo/ =&gt; /vagrant</span><br><span class="line">==&gt; default: Mounting shared folders...</span><br><span class="line">    default: /vagrant_data =&gt; C:/Users/Davy/data</span><br><span class="line">Vagrant was unable to mount VirtualBox shared folders. This is usually</span><br><span class="line">because the filesystem &quot;vboxsf&quot; is not available. This filesystem is</span><br><span class="line">made available via the VirtualBox Guest Additions and kernel module.</span><br><span class="line">Please verify that these guest additions are properly installed in the</span><br><span class="line">guest. This is not a bug in Vagrant and is usually caused by a faulty</span><br><span class="line">Vagrant box. For context, the command attempted was:</span><br><span class="line"></span><br><span class="line">mount -t vboxsf -o uid=1000,gid=1000 vagrant_data /vagrant_data</span><br><span class="line"></span><br><span class="line">The error output from the command was:</span><br><span class="line"></span><br><span class="line">mount: unknown filesystem type &#x27;vboxsf&#x27;</span><br></pre></td></tr></table></figure>

<p>这是因为 Vagrant 提供了多种同步方式，在使用 VirtualBox 的时候，缺省同步类型是 <a href="https://link.zhihu.com/?target=https%3A//www.vagrantup.com/docs/synced-folders/virtualbox.html">vboxsf 挂载文件系统</a>，它需要在虚拟机内部安装客户机增强包，也就是 <code>VirtualBox Guest Additions</code>（输出信息中也提示了）。</p>
<p>如何在虚机系统中安装 <code>guest additions</code> 要分操作系统而定，有点小坑，后面会细说，现在修改一下配置，明确指定同步类型是 <code>rsync</code>：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">config.vm.synced_folder &quot;../data&quot;, &quot;/vagrant_data&quot;, type: &quot;rsync&quot;</span><br></pre></td></tr></table></figure>

<p>这样表示仍然使用 <code>rsync</code> 来单向同步。</p>
<h3 id="更改虚机规格"><a href="#更改虚机规格" class="headerlink" title="更改虚机规格"></a>更改虚机规格</h3><p>VirtualBox 等虚拟机软件在 Vagrant 中被称为 Provider，虚机的规格等配置是和 Provider 相关的。因为 VirtualBox 用的最多，所以默认的配置提示是以 VirtualBox 举例。</p>
<p>如果想要了解其它 Provider 的配置，请参考 <a href="https://link.zhihu.com/?target=https%3A//www.vagrantup.com/docs/providers/">文档</a></p>
<p>把中间那一段取消注释，其它的可以删掉：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"># Provider-specific configuration so you can fine-tune various</span><br><span class="line"># backing providers for Vagrant. These expose provider-specific options.</span><br><span class="line"># Example for VirtualBox:</span><br><span class="line">#</span><br><span class="line"># config.vm.provider &quot;virtualbox&quot; do |vb|</span><br><span class="line">#   # Display the VirtualBox GUI when booting the machine</span><br><span class="line">#   vb.gui = true</span><br><span class="line">#</span><br><span class="line">#   # Customize the amount of memory on the VM:</span><br><span class="line">#   vb.memory = &quot;1024&quot;</span><br><span class="line"># end</span><br><span class="line">#</span><br><span class="line"># View the documentation for the provider you are using for more</span><br><span class="line"># information on available options.</span><br></pre></td></tr></table></figure>

<p>使用 VSCode 时，选中它们，然后按下快捷键 <code>Ctrl + /</code> 即可：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">config.vm.provider &quot;virtualbox&quot; do |vb|</span><br><span class="line">  # Display the VirtualBox GUI when booting the machine</span><br><span class="line">  vb.gui = true</span><br><span class="line"></span><br><span class="line">  # Customize the amount of memory on the VM:</span><br><span class="line">  vb.memory = &quot;1024&quot;</span><br><span class="line">end</span><br></pre></td></tr></table></figure>

<p><code>vb.gui = true</code> 是在虚机启动时自动打开 VirtualBox 的图形界面，这对服务器来说没什么用，直接删掉。</p>
<p>添加 CPU 的配置，同时修改内存大小：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">config.vm.provider &quot;virtualbox&quot; do |vb|</span><br><span class="line">  vb.cpus = 2</span><br><span class="line">  vb.memory = 2048</span><br><span class="line">end</span><br></pre></td></tr></table></figure>

<p>注意到，内存的大小单位是 MB，值是数字，默认的示例中有引号，实际也可以不加。</p>
<p>特别提醒一下，在 <a href="https://link.zhihu.com/?target=https%3A//www.vagrantup.com/docs/virtualbox/configuration.html">说明文档</a> 里给的例子，其中的变量名是 <code>v</code>，这其实是在双竖线中定义的，直接拷贝的时候要看清楚。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">config.vm.provider &quot;virtualbox&quot; do |v|</span><br><span class="line">  v.memory = 1024</span><br><span class="line">  v.cpus = 2</span><br><span class="line">end</span><br></pre></td></tr></table></figure>

<h3 id="Provision"><a href="#Provision" class="headerlink" title="Provision"></a>Provision</h3><p>Provision 是指在虚机初次创建的时候，Vagrant 自动去执行的构造任务，比如安装软件，更新系统配置等。</p>
<p>因为 box 往往只提供基础的系统（虽然我们可以自定义 box，但是并不是每次都要这么做，而且这样做会丧失一部分灵活性），有些东西仍然需要在创建虚机的时候完成。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"># Enable provisioning with a shell script. Additional provisioners such as</span><br><span class="line"># Ansible, Chef, Docker, Puppet and Salt are also available. Please see the</span><br><span class="line"># documentation for more information about their specific syntax and use.</span><br><span class="line"># config.vm.provision &quot;shell&quot;, inline: &lt;&lt;-SHELL</span><br><span class="line">#   apt-get update</span><br><span class="line">#   apt-get install -y apache2</span><br><span class="line"># SHELL</span><br></pre></td></tr></table></figure>

<p>因为这部分完全是个开放的内容，所以我们这里不过多讨论，来看一下什么情况下会触发 provision 的操作：</p>
<ul>
<li>某个环境初次执行 <code>vagrant up</code> 的时候</li>
<li>执行 <code>vagrant provision</code> 命令</li>
<li>重启的时候 <code>vagrant reload --provision</code>，带上 <code>--provision</code> 选项</li>
</ul>
<p>除了上面这些默认提示给出的配置项，Vagrantfile 还支持其它很多配置，具体请 <a href="https://link.zhihu.com/?target=https%3A//www.vagrantup.com/docs/vagrantfile/">查看文档</a>。</p>
<p>由于 Vagrantfile 本身是 Ruby 脚本，所以它并不仅仅是静态的配置文件，而且可以包含程序逻辑，例如在 <a href="https://link.zhihu.com/?target=https%3A//www.vagrantup.com/docs/multi-machine/">如何创建多个虚机</a> 中就有应用，有兴趣的可以自行研究。</p>
<h2 id="定制带客户机增强的-box"><a href="#定制带客户机增强的-box" class="headerlink" title="定制带客户机增强的 box"></a>定制带客户机增强的 box</h2><h3 id="下载-Guest-Addition"><a href="#下载-Guest-Addition" class="headerlink" title="下载 Guest Addition"></a>下载 Guest Addition</h3><p>VirtualBox 的<a href="https://link.zhihu.com/?target=https%3A//www.virtualbox.org/wiki/Downloads">下载页面</a>并没有直接给出 Guest Addtion 的下载链接，我们先在 VirtualBox 的任一下载链接上右键，复制链接地址，例如得到 <code>https://download.virtualbox.org/virtualbox/6.1.6/VirtualBox-6.1.6-137129-Win.exe</code>，去掉最后的文件名，把其中的路径 <code>https://download.virtualbox.org/virtualbox/6.1.6/</code> 在浏览器中打开，就能看到所有可下载的版本，在其中找到 <code>VBoxGuestAdditions_6.1.6.iso</code> 直接下载。</p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://pic2.zhimg.com/80/v2-6a207372c58ba6ff0bc7c8da9f5f015d_1440w.jpg" alt="img"></p>
<h3 id="安装-Guest-Addition"><a href="#安装-Guest-Addition" class="headerlink" title="安装 Guest Addition"></a>安装 Guest Addition</h3><p>重新使用 Vagrant 从原始的镜像启动一个干净的虚机。</p>
<p><code>VBoxGuestAdditions_6.1.6.iso</code> 需要以光盘的形式挂载到虚机上，但是默认启动的这个虚机是没有光驱的。添加虚拟光驱需要先将虚机关闭。</p>
<p>然后在 VirtualBox 界面上操作，打开 <code>设置</code>，选择 <code>存储</code>，点击 <code>添加虚拟光驱</code>，点击 <code>控制器： IDE</code>，选择 <code>VBoxGuestAdditions_6.1.6.iso</code>，点击 <code>OK</code></p>
<p>直接在 VirtualBox 上启动虚机，如果你在虚机菜单上选择 <code>设备</code> - <code>安装增强功能</code>，大概率是会遇到下面这样的错误，别管它，我们手动来安装。</p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://pic2.zhimg.com/80/v2-a12c3083ad70b943faaed4f822e6c7c5_1440w.jpg" alt="img"></p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://pic2.zhimg.com/80/v2-8be73777016fdb8ffc17ce6eb58e3179_1440w.jpg" alt="img"></p>
<p>使用 <code>vagrant/vagrant</code> 登录到虚机内，切换到 <code>root</code> 用户，查看虚拟光盘是否已经挂载上来了：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">$ sudo -i</span><br><span class="line"># lsblk</span><br><span class="line">NAME   MAJ:MIN RM SIZE RO TYPE MOUNTPOINT</span><br><span class="line">sda      8:0    0  40G  0 disk</span><br><span class="line">└─sda1   8:1    0  40G  0 part /</span><br><span class="line">sr0     11:0    1  57M  0 rom</span><br></pre></td></tr></table></figure>

<p>下面的 <code>sr0</code> 就是光盘设备，要把它挂载到文件系统中</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># mount /dev/sr0 /mnt/</span><br><span class="line">mount: /dev/sr0 is write-protected, mounting read-only</span><br><span class="line"># cd /mnt/</span><br><span class="line"># ls</span><br><span class="line">AUTORUN.INF  cert  OS2           TRANS.TBL                VBoxDarwinAdditionsUninstall.tool  VBoxSolarisAdditions.pkg        VBoxWindowsAdditions.exe</span><br><span class="line">autorun.sh   NT3x  runasroot.sh  VBoxDarwinAdditions.pkg  VBoxLinuxAdditions.run             VBoxWindowsAdditions-amd64.exe  VBoxWindowsAdditions-x86.exe</span><br></pre></td></tr></table></figure>

<p>在 Linux 系统中要运行 <code>VBoxLinuxAdditions.run</code>，这时候直接运行仍然会报错：</p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://pic2.zhimg.com/80/v2-48cba2e05faeddc156215d4a4896e61d_1440w.jpg" alt="img"></p>
<p>大致意思是要它需要内核的头文件来构建。</p>
<p>头文件通过安装 <code>kernel-devel</code> 就可以了，但是直接安装的版本是最新版本的，可能会当前的内核版本不一致，仍然是没用的。例如：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">[root@localhost mnt]# uname -r</span><br><span class="line">3.10.0-1062.12.1.el7.x86_64</span><br><span class="line">[root@localhost mnt]# yum info kernel-devel</span><br><span class="line">Installed Packages</span><br><span class="line">Name        : kernel-devel</span><br><span class="line">Arch        : x86_64</span><br><span class="line">Version     : 3.10.0</span><br><span class="line">Release     : 1127.el7</span><br><span class="line">Size        : 38 M</span><br><span class="line">Repo        : installed</span><br><span class="line">From repo   : base</span><br></pre></td></tr></table></figure>

<p>这里 <code>kernel-devel</code> 的 <code>Release</code> 版本号和系统内核版本不一致，所以仍然不行。</p>
<p>需要先更新一把，然后再安装（也可以先安装再更新）：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># yum update -y</span><br><span class="line"># yum install -y gcc kernel-devel</span><br></pre></td></tr></table></figure>

<blockquote>
<p>这里选择的是更新到最新版本，如果你的开发环境需要特定的内核版本，你也可以根据情况安装指定的版本，只要<strong>保证内核版本和头文件版本完全匹配</strong>。</p>
<p>Ubuntu 系统的安装方式有所不同，可以参考 <a href="https://link.zhihu.com/?target=https%3A//www.vagrantup.com/docs/virtualbox/boxes.html">Vagrant 的文档</a></p>
</blockquote>
<p>升级内核后需要重启虚机，然后再次尝试安装 Additions：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">[root@localhost mnt]# ./VBoxLinuxAdditions.run</span><br><span class="line">Verifying archive integrity... All good.</span><br><span class="line">Uncompressing VirtualBox 6.1.6 Guest Additions for Linux........</span><br><span class="line">VirtualBox Guest Additions installer</span><br><span class="line">Removing installed version 6.1.6 of VirtualBox Guest Additions...</span><br><span class="line">Copying additional installer modules ...</span><br><span class="line">Installing additional modules ...</span><br><span class="line">VirtualBox Guest Additions: Starting.</span><br><span class="line">VirtualBox Guest Additions: Building the VirtualBox Guest Additions kernel</span><br><span class="line">modules.  This may take a while.</span><br><span class="line">VirtualBox Guest Additions: To build modules for other installed kernels, run</span><br><span class="line">VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup &lt;version&gt;</span><br><span class="line">VirtualBox Guest Additions: or</span><br><span class="line">VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup all</span><br><span class="line">VirtualBox Guest Additions: Building the modules for kernel</span><br><span class="line">3.10.0-1127.el7.x86_64.</span><br><span class="line">VirtualBox Guest Additions: Running kernel modules will not be replaced until</span><br><span class="line">the system is restarted</span><br><span class="line"></span><br><span class="line"># 检查模块是否已经加载了</span><br><span class="line">[root@localhost mnt]# lsmod |grep vbox</span><br><span class="line">vboxvideo              35867  1</span><br><span class="line">ttm                    96673  1 vboxvideo</span><br><span class="line">drm_kms_helper        186531  1 vboxvideo</span><br><span class="line">drm                   456166  4 ttm,drm_kms_helper,vboxvideo</span><br><span class="line">vboxguest             349038  1</span><br><span class="line">[root@localhost mnt]#</span><br></pre></td></tr></table></figure>

<p>能够看到 <code>vboxguest</code> 就代表安装成功了。</p>
<h3 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h3><p>在 Vagrantfile 中添加同步文件夹设置，这次不再指定同步类型</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">config.vm.synced_folder &quot;../data&quot;, &quot;/vagrant_data&quot;</span><br></pre></td></tr></table></figure>

<p>然后执行 <code>vagrant reload</code></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">$ vagrant reload</span><br><span class="line">...</span><br><span class="line">==&gt; default: Checking for guest additions in VM...</span><br><span class="line">==&gt; default: Rsyncing folder: /cygdrive/c/Users/Davy/demo/ =&gt; /vagrant</span><br><span class="line">==&gt; default: Mounting shared folders...</span><br><span class="line">    default: /vagrant_data =&gt; C:/Users/Davy/data</span><br><span class="line">==&gt; default: Machine already provisioned. Run `vagrant provision` or use the `--provision`</span><br><span class="line">==&gt; default: flag to force provisioning. Provisioners marked to run always will still run.</span><br></pre></td></tr></table></figure>

<p>可以看到关于 additions 的提示信息没有了，新的同步文件夹也能正常同步了，这次的同步是双向的。我们可以先去同步文件夹随便创建一个文件：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">$ vagrant ssh</span><br><span class="line">Last login: Tue May  5 12:16:39 2020 from 10.0.2.2</span><br><span class="line">[vagrant@localhost ~]$ cd /vagrant_data/</span><br><span class="line">[vagrant@localhost vagrant_data]$ ls</span><br><span class="line">data.txt</span><br><span class="line">[vagrant@localhost vagrant_data]$ touch vm.txt   # 新建一个文件</span><br><span class="line">[vagrant@localhost vagrant_data]$ ls</span><br><span class="line">data.txt  vm.txt</span><br></pre></td></tr></table></figure>

<p>回到 Windows 宿主机上，<code>data</code> 文件夹下面也能看到 <code>vm.txt</code> 文件，</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Davy@Davy-Desktop MINGW64 ~/data</span><br><span class="line">$ ls</span><br><span class="line">data.txt  vm.txt</span><br></pre></td></tr></table></figure>

<p>这样，我们的 Guest Addition 就安装成功了。</p>
<h3 id="清理磁盘"><a href="#清理磁盘" class="headerlink" title="清理磁盘"></a>清理磁盘</h3><p>接下来我们来把这个好不容易才装上了增强包的虚机保存为新的镜像。</p>
<blockquote>
<p>这里你可能还想安装点其它软件，但是作为基础镜像，最好还是保持干净一点，不宜安装太多东西。后续可以在这个基础之上，再次构建其它特定的镜像。</p>
</blockquote>
<p>为了使做出来的镜像文件大小紧凑点，我们把刚才安装过程中的缓存也删掉：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum clean all</span><br></pre></td></tr></table></figure>

<p>我在打包过程中还遇到过 swapfile 占用磁盘空间的问题，导致镜像文件过大，可以这样检查：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">du /swapfile   # 查看是否有占用</span><br><span class="line">swapoff -a     # 关闭 SWAP</span><br><span class="line">rm -f /swapfile</span><br></pre></td></tr></table></figure>

<p>使用 <code>df -h</code> 命令查看磁盘占用情况，像我这次操作，磁盘根目录不到 2GB 的空间占用：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># df -h</span><br><span class="line">/dev/sda1        40G  1.5G   39G   4% /</span><br></pre></td></tr></table></figure>

<h3 id="打包为-box"><a href="#打包为-box" class="headerlink" title="打包为 box"></a>打包为 box</h3><p>执行 <code>vagrant package</code> 就可以把当前环境打包生成新的 box 文件：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$ vagrant  package</span><br><span class="line">    ==&gt; default: Attempting graceful shutdown of VM...</span><br><span class="line">==&gt; default: Clearing any previously set forwarded ports...</span><br><span class="line">==&gt; default: Exporting VM...</span><br><span class="line">==&gt; default: Compressing package to: C:/Users/Davy/demo/package.box</span><br></pre></td></tr></table></figure>

<p>生成的文件就在 Dockerfile 所在的目录，文件名默认是 <code>package.box</code>。大小不到 600MB。</p>
<p><strong>注意：</strong>，因为默认启动虚机时本地目录会 rsync 到虚机中，<code>package.box</code> 文件也会同步（拷贝）到虚机中，占用虚机磁盘。这时候如果二次执行打包，生成的文件大小会翻倍。</p>
<h3 id="添加到-vagrant-中"><a href="#添加到-vagrant-中" class="headerlink" title="添加到 vagrant 中"></a>添加到 vagrant 中</h3><p>继续使用下面的命令把新建的 box 添加到 vagrant 中：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ vagrant box add package.box --name davy/centos-7-base</span><br></pre></td></tr></table></figure>

<p>为了区分这是个人创建的基础镜像，加了个人用户名作为前缀，同时加了 <code>base</code> 后缀。</p>
<p>添加成功后，本地的 <code>package.box</code> 就可以删除了。</p>
<p>后续再创建虚机，使用下面的命令就可以了：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ vagrant init davy/centos-7-base</span><br></pre></td></tr></table></figure>

<h2 id="使用-SSH-客户端"><a href="#使用-SSH-客户端" class="headerlink" title="使用 SSH 客户端"></a>使用 SSH 客户端</h2><p><code>vagrant ssh</code> 命令虽然很方便，但是在 Windows 环境下，因为默认的命令行终端不太好用，所以往往还需要使用更专业的 SSH 客户端例如 XShell 或 SecureCRT。</p>
<p>默认的镜像只支持 private_key 的方式登录，<code>vagrant/vagrant</code> 可以在 VirtualBox 上登录系统，但是如果用来登录 SSH，会被拒绝。</p>
<p>当然你可以在制作镜像的时候修改 ssh 服务的配置，让它能够用密码登录，但是实际上用密钥更加方便。</p>
<p>先使用 <code>vagrant ssh-config</code> 命令可以看到 SSH 的配置：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">$ vagrant ssh-config</span><br><span class="line">Host default</span><br><span class="line">  HostName 127.0.0.1</span><br><span class="line">  User vagrant</span><br><span class="line">  Port 22222</span><br><span class="line">  UserKnownHostsFile /dev/null</span><br><span class="line">  StrictHostKeyChecking no</span><br><span class="line">  PasswordAuthentication no</span><br><span class="line">  IdentityFile E:/VirtualBox/.vagrant.d/boxes/davy-VAGRANTSLASH-centos-7-base/0/virtualbox/vagrant_private_key</span><br><span class="line">  IdentitiesOnly yes</span><br><span class="line">  LogLevel FATAL</span><br></pre></td></tr></table></figure>

<p>可以看到其中的 <code>IdentityFile</code> 就是私钥文件。</p>
<p>发现这个自定义 box 启动的虚机的密钥文件是固定在 <code>VAGRANT_HOME</code> 下的相关目录下。那么就好办了，直接在 SSH 客户端软件上导入这个私钥文件就可以了。</p>
<p>以 SecureCRT 为例：</p>
<p><img src= "https://gitee.com/kylincw/images/raw/master/loading.gif" data-lazy-src="https://pic1.zhimg.com/80/v2-26a045d8d3ae2db9f3f90e55050cfc9c_1440w.jpg" alt="img"></p>
<h2 id="使用模板文件"><a href="#使用模板文件" class="headerlink" title="使用模板文件"></a>使用模板文件</h2><p><code>vagrant init</code> 命令只是用来生成 Vagrantfile 文件，但是默认的配置选项每次都要修改也很麻烦。该命令提供了 <code>--template</code> 选项，可以指定一个模板文件，我们可以在自定义自己的模板文件。</p>
<p>这个模板文件的格式 <code>ERB</code> 是 <code>Ruby</code> 的模板语法，如果有 <code>Ruby on Rails</code> 开发经验的可能会比较熟悉。但是我们不用去学习这些细节。</p>
<p>可以从 <a href="https://link.zhihu.com/?target=https%3A//github.com/hashicorp/vagrant/blob/master/templates/commands/init/Vagrantfile.erb">这里</a> 拷贝一份原文件，还能在 Vagrant 的安装位置 <code>Vagrant\embedded\gems\2.2.7\gems\vagrant-2.2.7\templates\commands\init</code> 底下找到，并且有一个 <code>Vagrantfile.min.erb</code> 是去掉所有注释的：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">Vagrant.configure(&quot;2&quot;) do |config|</span><br><span class="line">  config.vm.box = &quot;&lt;%= box_name %&gt;&quot;</span><br><span class="line">  &lt;% if box_version -%&gt;</span><br><span class="line">  config.vm.box_version = &quot;&lt;%= box_version %&gt;&quot;</span><br><span class="line">  &lt;% end -%&gt;</span><br><span class="line">  &lt;% if box_url -%&gt;</span><br><span class="line">  config.vm.box_url = &quot;&lt;%= box_url %&gt;&quot;</span><br><span class="line">  &lt;% end -%&gt;</span><br><span class="line">end</span><br></pre></td></tr></table></figure>

<p>可以看到其中是怎么配置 <code>config.vm.box</code> 的。 像 <code>&lt;%</code> 这样的语法有兴趣可以自己去了解，这里我们只要把自己想要的配置项原样写上去就行了。</p>
<p>下面是我按照自己的需要写的：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">Vagrant.configure(&quot;2&quot;) do |config|</span><br><span class="line">  config.vm.box = &quot;&lt;%= box_name %&gt;&quot;</span><br><span class="line">  config.vm.network &quot;forwarded_port&quot;, guest: 22, host: 2222, id: &quot;ssh&quot;, disabled: &quot;true&quot;</span><br><span class="line">  config.vm.network &quot;forwarded_port&quot;, guest: 22, host: 22222</span><br><span class="line"></span><br><span class="line">  # config.vm.network &quot;private_network&quot;, ip: &quot;192.168.56.10&quot;</span><br><span class="line">  # config.vm.synced_folder &quot;../data&quot;, &quot;/data&quot;</span><br><span class="line"></span><br><span class="line">  config.vm.provider &quot;virtualbox&quot; do |vb|</span><br><span class="line">    # vb.name = &quot;give me a better name&quot;</span><br><span class="line">    vb.memory = &quot;1024&quot;</span><br><span class="line">  end</span><br><span class="line">end</span><br></pre></td></tr></table></figure>

<blockquote>
<p>不要有中文，不然会遇到编码的麻烦。</p>
</blockquote>
<p>其中像私有网络和同步文件夹配置，几乎每次基本都要，但是又不好固定，所以仍然以注释的形式保留，每次稍微改一下也很方便。</p>
<p>把这个文件找个目录，保存为 <code>vagrant.erb</code>。</p>
<p>接着在使用 <code>vagrant init</code> 的时候通过 <code>--tempate</code> 指定它就可以了，例如：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vagrant init davy/centos-7-base --tempate &quot;C:\Users\Davy\vagrant.erb&quot;</span><br></pre></td></tr></table></figure>

<p>显然，每次要记住并且输入这个模板文件也很麻烦的。可以通过设置环境变量 <code>VAGRANT_DEFAULT_TEMPLATE</code> 来一劳永逸地解决这个问题。</p>
<h2 id="尾声"><a href="#尾声" class="headerlink" title="尾声"></a>尾声</h2><p>费了莫大的力气，终于可以比较愉快地玩耍了。虽然也只是刚把基础镜像搞定了，后面可能还要针对不同用途的环境编写更加复杂的 Vagrantfile。</p>
<p>现在很多人刚认识到 Vagrant 之后都会问，<a target="_blank" rel="noopener" href="https://www.zhihu.com/question/32324376">Vagrant 和 Docker 的区别是什么？</a></p>
<p>在容器流行之前，Vagrant 就是用来编排虚机和自动部署开发环境的，有了 Docker/Kubernetes 之后，直接用容器来编排应用确实更香。但是还有一些工作，例如容器平台自身的安装，多节点集群的部署测试等，更方便用虚机解决。</p>
<p>此外，现在 Windows 中还可以通过 WSL 使用 Linux 系统，但是使用场景上还是有所不同。Vagrant 更多地用于快速搭建可重用的开发环境，从这个角度看，Vagrant 其实好比 IaaS 云平台，只不过规模局限在个人电脑上。</p>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="mailto:undefined">Kylin</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://www.codekylin.cn/47602.html">https://www.codekylin.cn/47602.html</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://www.codekylin.cn" target="_blank">Kylin</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/vagrant/">vagrant</a></div><div class="post_share"><div class="social-share" data-image="https://qiniu.codekylin.cn/img/20200418114719.jpg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/social-share.js/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/social-share.js/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button button--animated"><i class="fas fa-qrcode"></i> 打赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="https://qiniu.codekylin.cn/img/20200807181442.jpg" target="_blank"><img class="post-qr-code-img" data-lazy-src="https://qiniu.codekylin.cn/img/20200807181442.jpg" alt="微信"/></a><div class="post-qr-code-desc">微信</div></li><li class="reward-item"><a href="https://qiniu.codekylin.cn/img/20200807181505.jpg" target="_blank"><img class="post-qr-code-img" data-lazy-src="https://qiniu.codekylin.cn/img/20200807181505.jpg" alt="支付寶"/></a><div class="post-qr-code-desc">支付寶</div></li></ul></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/29138.html"><img class="prev-cover" data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-2k8wlg.jpg" onerror="onerror=null;src='/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">GitLab的安装使用</div></div></a></div><div class="next-post pull-right"><a href="/45434.html"><img class="next-cover" data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-3kp6yv.jpg" onerror="onerror=null;src='/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">Docker监控CIG</div></div></a></div></nav><hr/><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div class="vcomment" id="vcomment"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="card-info-avatar is-center"><img class="avatar-img" data-lazy-src="https://qiniu.codekylin.cn/img/20200807181526.jpg" onerror="this.onerror=null;this.src='https://qiniu.codekylin.cn/github/img/friend_404.gif'" alt="avatar"/><div class="author-info__name">Kylin</div><div class="author-info__description">学习不易，努力努力~</div></div><div class="card-info-data"><div class="card-info-data-item is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">362</div></a></div><div class="card-info-data-item is-center"><a href="/tags/"><div class="headline">标签</div><div class="length-num">427</div></a></div><div class="card-info-data-item is-center"><a href="/categories/"><div class="headline">分类</div><div class="length-num">101</div></a></div></div><a class="button--animated" id="card-info-btn"><i class="fas fa-bookmark"></i><span>加入书签</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://github.com/kylincw" target="_blank" title="Github"><i class="iconfont icon-github"></i></a><a class="social-icon" href="tencent://message/?Menu=yes&amp;uin=171346168&amp;Service=300&amp;sigT=45a1e5847943b64c6ff3990f8a9e644d2b31356cb0b4ac6b24663a3c8dd0f8aa12a595b1714f9d45" target="_blank" title="qq"><i class="iconfont icon-qq"></i></a><a class="social-icon" href="https://space.bilibili.com/53836035" target="_blank" title="BiliBili"><i class="iconfont icon-bilibili-line"></i></a><a class="social-icon" href="mailto:zhang171346168@qq.com" target="_blank" title="Email"><i class="iconfont icon-email1"></i></a><a class="social-icon" href="/atom.xml" target="_blank" title="RSS"><i class="iconfont icon-rss"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn card-announcement-animation"></i><span>公告</span></div><div class="announcement_content">学习不易，努力努力！</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%A6%82%E8%BF%B0"><span class="toc-number">1.</span> <span class="toc-text">概述</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AE%89%E8%A3%85%E8%BD%AF%E4%BB%B6"><span class="toc-number">2.</span> <span class="toc-text">安装软件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE%E8%99%9A%E6%9C%BA%E5%AD%98%E6%94%BE%E4%BD%8D%E7%BD%AE"><span class="toc-number">3.</span> <span class="toc-text">配置虚机存放位置</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%8B%E8%BD%BD%E8%99%9A%E6%9C%BA%E9%95%9C%E5%83%8F"><span class="toc-number">4.</span> <span class="toc-text">下载虚机镜像</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%B7%BB%E5%8A%A0-box"><span class="toc-number">5.</span> <span class="toc-text">添加 box</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Vagrant-%E5%9F%BA%E6%9C%AC%E6%93%8D%E4%BD%9C"><span class="toc-number">6.</span> <span class="toc-text">Vagrant 基本操作</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%96%B0%E5%BB%BA%E8%99%9A%E6%9C%BA"><span class="toc-number">6.1.</span> <span class="toc-text">新建虚机</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%90%AF%E5%8A%A8%E8%99%9A%E6%9C%BA"><span class="toc-number">6.2.</span> <span class="toc-text">启动虚机</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%9F%A5%E7%9C%8B%E8%99%9A%E6%9C%BA%E7%8A%B6%E6%80%81"><span class="toc-number">6.3.</span> <span class="toc-text">查看虚机状态</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%BF%9E%E6%8E%A5%E8%99%9A%E6%9C%BA"><span class="toc-number">6.4.</span> <span class="toc-text">连接虚机</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%81%9C%E6%AD%A2%E8%99%9A%E6%9C%BA"><span class="toc-number">6.5.</span> <span class="toc-text">停止虚机</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%9A%82%E5%81%9C%E8%99%9A%E6%9C%BA"><span class="toc-number">6.6.</span> <span class="toc-text">暂停虚机</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%81%A2%E5%A4%8D%E8%99%9A%E6%9C%BA"><span class="toc-number">6.7.</span> <span class="toc-text">恢复虚机</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%87%8D%E8%BD%BD%E8%99%9A%E6%9C%BA"><span class="toc-number">6.8.</span> <span class="toc-text">重载虚机</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%A0%E9%99%A4%E8%99%9A%E6%9C%BA"><span class="toc-number">6.9.</span> <span class="toc-text">删除虚机</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%88%9D%E8%AF%86-Vagrantfile"><span class="toc-number">7.</span> <span class="toc-text">初识 Vagrantfile</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89%E9%85%8D%E7%BD%AE-Vagrantfile"><span class="toc-number">8.</span> <span class="toc-text">自定义配置 Vagrantfile</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91"><span class="toc-number">8.1.</span> <span class="toc-text">配置端口转发</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE%E7%A7%81%E6%9C%89%E7%BD%91%E7%BB%9C"><span class="toc-number">8.2.</span> <span class="toc-text">配置私有网络</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE%E5%85%AC%E5%85%B1%E7%BD%91%E7%BB%9C"><span class="toc-number">8.3.</span> <span class="toc-text">配置公共网络</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE%E5%90%8C%E6%AD%A5%E6%96%87%E4%BB%B6%E5%A4%B9"><span class="toc-number">8.4.</span> <span class="toc-text">配置同步文件夹</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%9B%B4%E6%94%B9%E8%99%9A%E6%9C%BA%E8%A7%84%E6%A0%BC"><span class="toc-number">8.5.</span> <span class="toc-text">更改虚机规格</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Provision"><span class="toc-number">8.6.</span> <span class="toc-text">Provision</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AE%9A%E5%88%B6%E5%B8%A6%E5%AE%A2%E6%88%B7%E6%9C%BA%E5%A2%9E%E5%BC%BA%E7%9A%84-box"><span class="toc-number">9.</span> <span class="toc-text">定制带客户机增强的 box</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%8B%E8%BD%BD-Guest-Addition"><span class="toc-number">9.1.</span> <span class="toc-text">下载 Guest Addition</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%89%E8%A3%85-Guest-Addition"><span class="toc-number">9.2.</span> <span class="toc-text">安装 Guest Addition</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%B5%8B%E8%AF%95"><span class="toc-number">9.3.</span> <span class="toc-text">测试</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%B8%85%E7%90%86%E7%A3%81%E7%9B%98"><span class="toc-number">9.4.</span> <span class="toc-text">清理磁盘</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%89%93%E5%8C%85%E4%B8%BA-box"><span class="toc-number">9.5.</span> <span class="toc-text">打包为 box</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%B7%BB%E5%8A%A0%E5%88%B0-vagrant-%E4%B8%AD"><span class="toc-number">9.6.</span> <span class="toc-text">添加到 vagrant 中</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8-SSH-%E5%AE%A2%E6%88%B7%E7%AB%AF"><span class="toc-number">10.</span> <span class="toc-text">使用 SSH 客户端</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E6%A8%A1%E6%9D%BF%E6%96%87%E4%BB%B6"><span class="toc-number">11.</span> <span class="toc-text">使用模板文件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%B0%BE%E5%A3%B0"><span class="toc-number">12.</span> <span class="toc-text">尾声</span></a></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/56352.html" title="be动词"><img data-lazy-src="https://qiniu.codekylin.cn/github/img/img/博客封面10.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="be动词"/></a><div class="content"><a class="title" href="/56352.html" title="be动词">be动词</a><time datetime="2022-07-12T11:47:29.800Z" title="更新于 2022-07-12 19:47:29">2022-07-12</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/36436.html" title="JVM堆内存"><img data-lazy-src="https://qiniu.codekylin.cn/img/20200418115059.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="JVM堆内存"/></a><div class="content"><a class="title" href="/36436.html" title="JVM堆内存">JVM堆内存</a><time datetime="2022-07-12T11:47:29.800Z" title="更新于 2022-07-12 19:47:29">2022-07-12</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/44292.html" title="Java多线程详解"><img data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-eorjzk.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Java多线程详解"/></a><div class="content"><a class="title" href="/44292.html" title="Java多线程详解">Java多线程详解</a><time datetime="2022-07-12T11:47:29.800Z" title="更新于 2022-07-12 19:47:29">2022-07-12</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/40200.html" title="谷粒商城记录"><img data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-6qvvrx.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="谷粒商城记录"/></a><div class="content"><a class="title" href="/40200.html" title="谷粒商城记录">谷粒商城记录</a><time datetime="2022-07-12T11:47:29.800Z" title="更新于 2022-07-12 19:47:29">2022-07-12</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/27082.html" title="Spring学习-3"><img data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-4x28xo.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Spring学习-3"/></a><div class="content"><a class="title" href="/27082.html" title="Spring学习-3">Spring学习-3</a><time datetime="2022-07-12T11:47:29.799Z" title="更新于 2022-07-12 19:47:29">2022-07-12</time></div></div></div></div></div></div></main><footer id="footer" style="background-image: url('https://qiniu.codekylin.cn/img/20200418114719.jpg')"><div id="footer-wrap"><div class="copyright">&copy;2019 - 2022 By Kylin</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div><div class="footer_custom_text"><a target="_blank" rel="noopener" href="https://beian.miit.gov.cn/"><img class="icp-icon" src="https://img.alicdn.com/tfs/TB1..50QpXXXXX7XpXXXXXXXXXX-40-40.png"><span>湘ICP备2022005420号-1</span></a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="font-plus" type="button" title="放大字体"><i class="fas fa-plus"></i></button><button id="font-minus" type="button" title="缩小字体"><i class="fas fa-minus"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fas fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><div class="search-dialog__title" id="local-search-title">本地搜索</div><div id="local-input-panel"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div></div><hr/><div id="local-search-results"></div><span class="search-close-button"><i class="fas fa-times"></i></span></div><div id="search-mask"></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/instant.page/instantpage.min.js" type="module"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><script src="/js/search/local-search.js"></script><div class="js-pjax"><script>function loadValine () {
  function initValine () {
    const valine = new Valine(Object.assign({
      el: '#vcomment',
      appId: 'ClIyIUhj1ue2rcRTsApYCR50-gzGzoHsz',
      appKey: 'ATug9IScYQBHILhKWEqBHYxM',
      placeholder: '昵称填入QQ号能获取到QQ头像哦~请输入正确的邮箱地址，你将会快速收到我的回复并且通过邮件通知你！~',
      avatar: 'robohash',
      meta: 'nick,mail,link'.split(','),
      pageSize: '10',
      lang: 'zh-cn',
      recordIP: false,
      serverURLs: 'https://cliyiuhj.lc-cn-n1-shared.com',
      emojiCDN: '',
      emojiMaps: "",
      enableQQ: true,
      path: window.location.pathname,
      requiredFields: ["nick,mail"],
      visitor: false
    }, null))
  }

  if (typeof Valine === 'function') initValine() 
  else getScript('https://cdn.jsdelivr.net/npm/valine/dist/Valine.min.js').then(initValine)
}

if ('Valine' === 'Valine' || !true) {
  if (true) btf.loadComment(document.getElementById('vcomment'),loadValine)
  else setTimeout(loadValine, 0)
} else {
  function loadOtherComment () {
    loadValine()
  }
}</script></div><script defer="defer" id="ribbon" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/canvas-ribbon.min.js" size="150" alpha="0.6" zIndex="-1" mobile="false" data-click="true"></script><script defer="defer" id="fluttering_ribbon" mobile="false" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/canvas-fluttering-ribbon.min.js"></script></div></body></html>